﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 基于彭轶的Demo实时Rdeis读写操作
{
    public class Redis数据提交
    {
        int i = 1;
        public void 添加数据到redis()
        {
            StackExchange.Redis.ConnectionMultiplexer conn = StackExchange.Redis.ConnectionMultiplexer.Connect("192.168.2.110:6379");
            //并行异步无序处理
            conn.PreserveAsyncOrder = false;
            //获取发布订阅功能
            var subscriber所有订阅 = conn.GetSubscriber();
            string sss = "示例实时数据" + (i++);
            //发布一个
            subscriber所有订阅.Publish("实时数据", sss);
            //订阅RedisChannel, RedisValue
            subscriber所有订阅.Subscribe("实时数据", abc);
            //发布一个
            subscriber所有订阅.Publish("实时数据", "示例实时数据" + (i++));



        }

        void abc(StackExchange.Redis.RedisChannel c, StackExchange.Redis.RedisValue v)
        {
            var sbc = 0;

        }


        public string 实时数据通知名 = "INREAL";

        public bool IsCanRuning = true;
        /// <summary>
        /// Redis联接
        /// </summary>
        StackExchange.Redis.ConnectionMultiplexer rdidsConn = null;

        /// <summary>
        /// 生成发布数据的方法 
        /// </summary>
        /// <param name="thrnum">生成的线程数据</param>
        /// <param name="speed">最高生成速度</param>
        public void 生成发布数据(int thrnum, int speed)
        {
            InitConn();

            while (IsCanRuning)
            {
                生成发布数据1(thrnum, speed);
            }
        }

        protected void InitConn()
        {
            try
            {
                rdidsConn = StackExchange.Redis.ConnectionMultiplexer.Connect("192.168.2.110:6379");
            }
            catch (Exception ex) { Console.WriteLine(ex); }
        }
        //产生模拟数据
        string demoStr = string.Join(",", System.Linq.Enumerable.Range(5000, 500).Select(p => p.ToString("d4")).ToArray());


        protected void 生成发布数据1(int thrnum, int speed)
        {

            DateTime dt = DateTime.Now;

            //判断Redis联接是否有效,异常处理
            if (rdidsConn != null && rdidsConn.IsConnected)
            {
                //获取发布订阅对像
                var sub = rdidsConn.GetSubscriber();
                Dictionary<int, StackExchange.Redis.ISubscriber> subs = new Dictionary<int, StackExchange.Redis.ISubscriber>();
                for (int i = 0; i < thrnum; i++)
                {
                    subs.Add(i, rdidsConn.GetSubscriber());
                }



                //并行发布实时数据
                System.Threading.Tasks.Parallel.For(1, speed, new ParallelOptions() { MaxDegreeOfParallelism = thrnum }, (n) =>
                {
                    //var handler= sub.PublishAsync(实时数据通知名, demoStr);
                    // sub.Wait(handler);
                    //sub.Publish(实时数据通知名, demoStr);  
                    try
                    {
                        var csub = subs[n % thrnum];
                        //联接断开时直接返回
                        if (!csub.IsConnected()) { return; }
                        csub.Publish(实时数据通知名, DateTime.Now + ";" + demoStr);
                    }
                    //联接断开异常
                    catch (StackExchange.Redis.RedisConnectionException) { }
                    catch (System.TimeoutException) { }


                });
            }

            else
            {
                if (rdidsConn == null)
                {
                    InitConn();
                }
            }


            //时间差毫秒
            double ss = (DateTime.Now - dt).TotalMilliseconds;
            //暂时停止 
            if (ss < 1000)
            {
                System.Threading.Thread.Sleep(1000 - (int)ss);
            }
            Console.WriteLine("{0:F2}/s", (speed / ss * 1000));

        }

    }
}
